<template>
  <div class="page device-page">
    <div class="page-title-box card-wrapper">
      <span class="page-title-text">申请管理</span>

      <div class="page-title-options">
        <div class="condition-box">
          <div class="condition-item">
            <span class="label">申请人：</span>
            <a-select class="select-value" v-model:value="conditionState.applyAccountId" placeholder="请选择" allow-clear @change="handleSearch">
              <a-select-option v-for="item in personList" :value="item.value" :key="item.value">{{item.label}}</a-select-option>
            </a-select>
          </div>
          <div class="condition-item">
            <span class="label">申请状态：</span>
            <a-select class="select-value" v-model:value="conditionState.status" placeholder="请选择" @change="handleSearch">
              <a-select-option :value="''">全部</a-select-option>
              <a-select-option :value="ApplyStatus.Pending">待审批</a-select-option>
              <a-select-option :value="ApplyStatus.Passed">已通过</a-select-option>
              <a-select-option :value="ApplyStatus.Rejected">已拒绝</a-select-option>
              <a-select-option :value="ApplyStatus.Canceled">已取消</a-select-option>
            </a-select>
          </div>
          <div class="condition-item">
            <a-button type="primary" @click="handleSearch" :loading="searchLoading">查询</a-button>
          </div>
        </div>
        <a-button type="primary" @click="handlePopCreateModal">创建申请</a-button>
      </div>
    </div>
    <div class="page-list-content card-wrapper">
      <a-table :data-source="tableData" :columns="columns" :pagination="false" :loading="searchLoading">
        <template #bodyCell="{record, column}">
          <template v-if="column.dataIndex === 'applyName'">
            <span>{{record.applyUserInfo.name}}</span>
          </template>
          <template v-if="column.dataIndex === 'deviceName'">
            <span>{{record.deviceInfo.deviceName}}</span>
          </template>
          <template v-if="column.dataIndex === 'useTime'">
            <span>{{record.applyUseDate}} [{{record.applyUseTimeRange}}]</span>
          </template>
          <template v-if="column.dataIndex === 'nextApproveName'">
            <span>{{record.approveUserInfo ? record.approveUserInfo.name : ''}}</span>
          </template>
          <template v-if="column.dataIndex === 'applyTime'">
            <span>{{formatTs(Number(record.applyTime))}}</span>
          </template>
          <template v-if="column.dataIndex === 'status'">
            <span class="status-text-pending" v-if="record.status === ApplyStatus.Pending">待审批</span>
            <span class="status-text-success" v-if="record.status === ApplyStatus.Passed">已通过</span>
            <span class="status-text-error" v-if="record.status === ApplyStatus.Rejected">已拒绝</span>
            <span class="status-text-disabled" v-if="record.status === ApplyStatus.Canceled">已取消</span>
          </template>
          <template v-if="column.dataIndex === 'option'">
            <a-button type="link" @click="handlePopDetailModal(record)">查看</a-button>
            <a-button type="link" v-if="record.status === ApplyStatus.Pending" @click="handlePopApproveModal(record)">代审批</a-button>
            <a-popconfirm v-if="record.status === ApplyStatus.Pending" title="确定要取消申请吗？" ok-text="确定" cancel-text="取消" @confirm="handleCancelApply(record)">
              <a-button type="link" danger>取消</a-button>
            </a-popconfirm>

          </template>
        </template>
      </a-table>
      <div class="pagination-box">
        <a-pagination
            v-model:current="pagination.pageIndex"
            v-model:page-size="pagination.pageSize"
            :total="pagination.total"
            :show-total="total => `共 ${total} 条`"
        @showSizeChange="handlePageSizeChange"
        @change="handleChange"/>
      </div>
      <a-modal v-model:visible="detailModalVisible" width="30%" title="申请详情" :footer="false">
        <div class="detail-row">
          <div class="detail-col">
            <span class="label">申请人：</span>
            <span class="value">{{detailObj.detail.applyUserInfo.name}}</span>
          </div>
          <div class="detail-col">
            <span class="label">申请设备：</span>
            <span class="value">{{detailObj.detail.deviceInfo.deviceName}}</span>
          </div>
        </div>
        <div class="detail-row">
          <div class="detail-col">
            <span class="label">使用时间：</span>
            <span class="value">{{detailObj.detail.applyUseDate}} [{{detailObj.detail.applyUseTimeRange}}]</span>
          </div>
          <div class="detail-col">
            <span class="label">审批人员：</span>
            <span class="value">{{detailObj.detail.approvePersonNames}}</span>
          </div>
        </div>
        <div class="detail-row">
          <div class="detail-col">
            <span class="label">申请时间：</span>
            <span class="value">{{formatTs(Number(detailObj.detail.applyTime))}}</span>
          </div>
          <div class="detail-col">
            <span class="label">状态：</span>
            <span class="value status-text-pending" v-if="detailObj.detail.status === ApplyStatus.Pending">待审批</span>
            <span class="value status-text-success" v-if="detailObj.detail.status === ApplyStatus.Passed">已通过</span>
            <span class="value status-text-error" v-if="detailObj.detail.status === ApplyStatus.Rejected">已拒绝</span>
            <span class="value status-text-disabled" v-if="detailObj.detail.status === ApplyStatus.Canceled">已取消</span>
          </div>
        </div>
        <div class="detail-list-row">
          <div class="detail-title">审批记录</div>
          <div class="detail-approve-list">
            <div class="approve-item" v-for="approve in detailObj.approveList" :key="approve.id">
              <div class="approve-info">
                <span class="time">{{formatTs(Number(approve.approveTime))}}</span>
                <span class="name">【{{approve.approveUserInfo.name}}】审批：</span>
                <span class="status status-text-success" v-if="approve.status === ApproveStatus.Passed">通过</span>
                <span class="status status-text-error" v-if="approve.status === ApproveStatus.Rejected">拒绝</span>
              </div>
              <div class="remark">备注：{{approve.approveRemark}}</div>
            </div>
          </div>
        </div>
      </a-modal>
      <a-modal v-model:visible="modalVisible" width="80%" title="创建申请" :footer="null">
        <a-form
            ref="formRef"
            layout="vertical"
            :model="formState"
            name="basic"
            autocomplete="off"
            @finish="onFinish">
          <a-form-item
              label="申请设备"
              name="deviceSn"
              :rules="[{ required: true, trigger: 'blur', message: '设备必填' }]">
            <a-select class="input-item" v-model:value="formState.deviceSn" :options="deviceList" @change="handleDeviceChange"></a-select>
          </a-form-item>
          <a-form-item
              label="申请人"
              name="applyAccountId"
              :rules="[{ required: true, trigger: 'blur', message: '申请人必填' }]">
            <a-select class="input-item" v-model:value="formState.applyAccountId" :options="personList"></a-select>
          </a-form-item>
          <a-form-item
              label="审批类型"
              name="approveAccountIdList">
            <a-select class="input-item" v-model:value="formState.approveAccountIdList" :options="applyCategoryList"></a-select>
          </a-form-item>
          <a-form-item
              label="使用时段"
              name="applyUseTimeRangeArr">
            <a-range-picker
                class="input-item"
                v-model:value="formState.applyUseTimeRangeArr"
                picker="time"
                :show-time="{ format: 'HH:mm' }"
                format="HH:mm"
                value-format="HH:mm"
                :placeholder="['开始时间', '结束时间']"/>
          </a-form-item>
          <a-form-item
              label="使用日期"
              name="applyUseDate">
            <a-form-item-rest>
              <a-calendar v-model:value="formState.applyUseDate" value-format="YYYY-MM-DD">
                <template #dateCellRender="{ current }">
                  <div class="time-range-tags" v-if="formState.deviceSn && devicePlanObj[formState.deviceSn] && devicePlanObj[formState.deviceSn][current.format('YYYY-MM-DD')]">
                    <span class="tag-text tag-error-text" v-for="rn in devicePlanObj[formState.deviceSn][current.format('YYYY-MM-DD')]" :key="rn">{{rn}}</span>
                  </div>
                </template>
              </a-calendar>
            </a-form-item-rest>
          </a-form-item>
          <a-form-item
              label="申请备注"
              name="applyRemark">
            <a-input class="input-item" v-model:value="formState.applyRemark" />
          </a-form-item>

          <a-form-item>
            <div class="btn-row">
              <a-button @click="modalVisible = false">取消</a-button>
              <a-button type="primary" html-type="submit">保存</a-button>
            </div>
          </a-form-item>
        </a-form>
      </a-modal>
      <a-modal v-model:visible="approveModalVisible" width="30%" title="代审批" :footer="null">
        <a-form
            ref="approveFormRef"
            layout="vertical"
            :model="approveFormState"
            name="basic"
            autocomplete="off"
            @finish="onApproveFinish">
          <a-form-item
              label="审批人"
              name="approveAccountId"
              :rules="[{ required: true, trigger: 'blur', message: '审批人必填' }]">
            <a-select class="input-item" :disabled="true" v-model:value="approveFormState.approveAccountId" :options="personList"></a-select>
          </a-form-item>
          <a-form-item
              label="审批状态"
              name="status"
              :rules="[{ required: true, trigger: 'blur', message: '审批状态必填' }]">
            <a-select class="input-item" v-model:value="approveFormState.status">
              <a-select-option :value="ApproveStatus.Passed">通过</a-select-option>
              <a-select-option :value="ApproveStatus.Rejected">拒绝</a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item
              label="审批备注"
              name="approveRemark">
            <a-input class="input-item" v-model:value="approveFormState.approveRemark" />
          </a-form-item>
          <a-form-item>
            <div class="btn-row">
              <a-button @click="approveModalVisible = false">取消</a-button>
              <a-button type="primary" html-type="submit">保存</a-button>
            </div>
          </a-form-item>
        </a-form>
      </a-modal>
    </div>
  </div>
</template>

<script setup lang="ts">
import {nextTick, onMounted, ref, createVNode} from 'vue'
import dayjs from 'dayjs';
import {
  ApplyCategoryItem,
  ApplyCategoryStatus,
  ApplyItem,
  ApplyStatus,
  ApproveItem,
  ApproveStatus,
  DeviceItem,
  DeviceStatus,
  OptionItem,
  PersonItem,
  PersonStatus,
} from "../../types/common";
import {formatTs, judgeCanUse} from '../../common/utils'
import applyApi from '../../api/apply/index';
import {message, Modal} from "ant-design-vue";
import {ExclamationCircleOutlined} from '@ant-design/icons-vue'
import personApi from "../../api/person";
import deviceApi from "../../api/device/index";
import applyCategoryApi from "../../api/apply-category/index";
import approveApi from "../../api/approve/index";

const modalVisible = ref(false)
const searchLoading = ref(false)
const conditionState = ref({
  applyAccountId: undefined,
  status: ApplyStatus.Pending
})
const pagination = ref({
  pageIndex: 1,
  pageSize: 10,
  total: 0,
})
const formRef = ref()
const formState = ref<ApplyItem>({
  id: '',
  deviceSn: '',
  applyUseDate: '',
  applyUseTimeRange: '',
  applyUseTimeRangeArr: [],
  applyAccountId: '',
  approveAccountIdList: '',
  nextApproveAccountId: '',
  applyTime: '',
  applyRemark: '',
  status: ApplyStatus.Pending,
  approvePersonNames: ''
})
const approveFormRef = ref()
const approveFormState = ref<ApproveItem>({
  id: '',
  applyId: '',
  deviceSn: '',
  applyAccountId: '',
  approveAccountId: '',
  approveTime: '',
  approveRemark: '',
  status: ApproveStatus.Passed
})
const tableData = ref<ApplyItem[]>([])
const columns = [
  {
    title: '申请人',
    dataIndex: 'applyName',
    key: 'applyName',
  },{
    title: '申请设备',
    dataIndex: 'deviceName',
    key: 'deviceName',
  },{
    title: '使用时间',
    dataIndex: 'useTime',
    key: 'useTime',
  },{
    title: '下一个审批人',
    dataIndex: 'nextApproveName',
    key: 'nextApproveName',
  },{
    title: '审批人员',
    dataIndex: 'approvePersonNames',
    key: 'approvePersonNames',
  },{
    title: '申请时间',
    dataIndex: 'applyTime',
    key: 'applyTime',
  },{
    title: '备注',
    dataIndex: 'applyRemark',
    key: 'applyRemark',
  },{
    title: '状态',
    dataIndex: 'status',
    key: 'status',
  },{
    title: '操作',
    dataIndex: 'option',
    key: 'option',
  },

]

const detailObj = ref({
  approveList: [],
  detail: {
    applyUserInfo: {},
    deviceInfo: {},
  },
  nextApproveUser: {}
})
const detailModalVisible = ref(false)
const personCacheObj: {[key: string]: PersonItem} = {}
const personList = ref<OptionItem[]>([])
const getPersonList = async () => {
  try {
    const res = await personApi.getList()
    if (res.data && res.data.length) {
      res.data.forEach((p: PersonItem) => {
        personList.value.push({
          label: p.name,
          value: p.accountId,
          disabled: p.status !== PersonStatus.Normal,
        })
        personCacheObj[p.accountId] = p
      })
    }
  } catch(e){

  }
}
const deviceList = ref<OptionItem[]>([])
const getDeviceList = () => {
  deviceApi.getList(DeviceStatus.Normal).then((res) => {
    if (res.data && res.data.length) {
      res.data.forEach((d: DeviceItem) => {
        deviceList.value.push({
          label: d.deviceName,
          value: d.deviceSn,
          disabled: d.status !== DeviceStatus.Normal,
        })
      })
    }
  })
}
getDeviceList()
const applyCategoryList = ref<OptionItem[]>([])
const getApplyCategoryList = () => {
  applyCategoryApi.getList().then((res) => {
    if (res.data && res.data.length) {
      res.data.forEach((c: ApplyCategoryItem) => {
        applyCategoryList.value.push({
          label: c.name,
          value: c.approveAccountIds,
          disabled: c.status !== ApplyCategoryStatus.Normal
        })
      })
    }
  })
}
getApplyCategoryList()
const devicePlanObj: any = ref({})
const getDevicePlanObj = async (deviceSn: string) => {
  devicePlanObj.value = {}
  try {
    const res = await applyApi.getDevicePlan(deviceSn)
    if (res.data) {
      devicePlanObj.value[deviceSn] = res.data
    }
  } catch(e){
    console.log(e)
  }
}
const handleDeviceChange = async () => {
  await getDevicePlanObj(formState.value.deviceSn)
}
const getDetail = (id: string) => {
  applyApi.detail(id).then((res) => {
    if (res.data) {
      res.data.detail.approvePersonNames = ''
      if (res.data.detail.approveAccountIdList) {
        const approve: string[] = []
        const approveArr = res.data.detail.approveAccountIdList.split(',')
        approveArr.forEach((id: string) => {
          if (id && personCacheObj[id]) {
            approve.push(personCacheObj[id].name)
          }
        })
        res.data.detail.approvePersonNames = approve.join(',')
      }
      detailObj.value = res.data
    }
  })
}
const getPaginationData = async () => {
  try {
    const res = await applyApi.getList({
      pageIndex: pagination.value.pageIndex,
      pageSize: pagination.value.pageSize,
      ...conditionState.value
    })
    if (res.data && res.data.data) {
      res.data.data.forEach((apply: ApplyItem) => {
        apply.approvePersonNames = ''
        if (apply.approveAccountIdList) {
          const approve: string[] = []
          const approveArr = apply.approveAccountIdList.split(',')
          approveArr.forEach((id: string) => {
            if (id && personCacheObj[id]) {
              approve.push(personCacheObj[id].name)
            }
          })
          apply.approvePersonNames = approve.join(',')
        }
      })
      tableData.value = res.data.data
      pagination.value.total = res.data.recordTotal
    } else {
      tableData.value = []
      pagination.value.total = 0
    }
  } catch(e){
    console.log(e)
    tableData.value = []
    pagination.value.total = 0
  }
}
const handleSearch = async () => {
  searchLoading.value = true
  pagination.value.pageIndex = 1
  await getPaginationData()
  searchLoading.value = false
}
// 页码或 pageSize 改变的回调，参数是改变后的页码及每页条数
const handleChange = (page: number, pageSize: number) => {}
// pageSize 变化的回调
const handlePageSizeChange = (current: number, size: number) => {}

onMounted(async () => {
  await getPersonList()
  handleSearch()
})
const handleCancelApply = (item: ApplyItem) => {
  applyApi.cancel(item.id).then((res) => {
    if (res.code === 0) {
      message.success('取消成功')
      handleSearch()
    } else {
      message.error(res.message || '取消失败')
    }
  }).catch((e: any) => {
    console.log(e)
    message.error('服务异常')
  })
}
const handlePopDetailModal = (item: ApplyItem) => {
  getDetail(item.id)
  detailModalVisible.value = true
}
const handlePopCreateModal = () => {
  formState.value = {
    id: '',
    deviceSn: '',
    applyUseDate: dayjs().format('YYYY-MM-DD'),
    applyUseTimeRange: '',
    applyUseTimeRangeArr: [],
    applyAccountId: '',
    approveAccountIdList: undefined,
    nextApproveAccountId: '',
    applyTime: '',
    applyRemark: '',
    status: ApplyStatus.Pending,
    approvePersonNames: ''
  }
  modalVisible.value = true
  nextTick(() => {
    formRef.value.clearValidate()
  })
}
const approveModalVisible = ref(false)
let currentApply: ApplyItem = null as never
const handlePopApproveModal = (item: ApplyItem) => {
  currentApply = item
  approveFormState.value = {
    id: '',
    applyId: item.id,
    deviceSn: item.deviceSn,
    applyAccountId: item.applyAccountId,
    approveAccountId: item.nextApproveAccountId,
    approveTime: '',
    approveRemark: '',
    status: ApproveStatus.Passed
  }
  approveModalVisible.value = true
  nextTick(() => {
    approveFormRef.value.clearValidate()
  })
}
const getIntersection = () => {
  let intersectionArr: string[] = []
  const applyUseTimeRangeArr = formState.value.applyUseTimeRangeArr
  const applyUseDate = formState.value.applyUseDate
  if (applyUseTimeRangeArr && applyUseTimeRangeArr.length == 2) {
    if (devicePlanObj.value[formState.value.deviceSn] && devicePlanObj.value[formState.value.deviceSn][applyUseDate]) {
      intersectionArr = judgeCanUse(applyUseTimeRangeArr[0], applyUseTimeRangeArr[1], devicePlanObj.value[formState.value.deviceSn][applyUseDate])
    }
  }
  return intersectionArr
}
const executeSubmit = () => {
  formState.value.applyUseTimeRange = formState.value.applyUseTimeRangeArr.join('-')
  applyApi.add(formState.value).then((res) => {
    if (res.code === 0) {
      message.success('创建成功')
      handleSearch()
      modalVisible.value = false
    } else {
      message.error(res.message || '创建失败')
    }
  }).catch((e: any) => {
    console.log(e)
    message.error('服务异常')
  })
}
const onFinish = () => {
  if (formState.value.approveAccountIdList === undefined) {
    message.error('请选择审批类型')
    return
  }
  const applyUseTimeRangeArr = formState.value.applyUseTimeRangeArr
  const applyUseDate = formState.value.applyUseDate
  if (!applyUseTimeRangeArr || applyUseTimeRangeArr.length < 2) {
    message.error('请选择使用时段')
    return
  }
  const intersectionArr = getIntersection()
  if (intersectionArr.length) {
    Modal.confirm({
      title: '温馨提示',
      icon: createVNode(ExclamationCircleOutlined),
      content: `您申请的使用时段与已存在的【${intersectionArr.join(',')}】时段有冲突，确定继续申请吗?`,
      onOk() {
        executeSubmit()
        return Promise.resolve()
      },
      // eslint-disable-next-line @typescript-eslint/no-empty-function
      onCancel() {},
    });
  } else {
    executeSubmit()
  }

}
const onApproveFinish = () => {
  approveApi.add(approveFormState.value).then((res) => {
    if (res.code === 0) {
      message.success('审批成功')
      handleSearch()
      approveModalVisible.value = false
    } else {
      message.error(res.message || '审批失败')
    }
  }).catch((e: any) => {
    console.log(e)
    message.error('服务异常')
  })
}
</script>

<style scoped lang="less">
.pagination-box{
  padding: 10px 0;
}
.condition-box{
  margin-right: 20px;
}
.condition-item{
  .select-value{
    width: 140px;
  }
}
.detail-row{
  position: relative;
  margin-top: 15px;
  display: flex;
  align-items: center;
  justify-content: space-between;

}
.detail-list-row{
  position: relative;
  margin-top: 15px;
  .detail-title{
    font-weight: 700;
    padding: 5px 0;
  }
  .detail-approve-list{
    position: relative;
    .approve-item{
      padding: 10px;
      border-bottom: 1px solid #ededed;
      .remark{
        padding-top: 5px;
      }
    }
  }
}
.time-range-tags{
  position: relative;
  .tag-text{
    margin-bottom: 5px;
    display: inline-block;
    &+.tag-text{
      margin-left: 5px;
    }
  }

}
.input-item{
  width: 320px;
}
</style>
